package com.company.bookstore.schedule;

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * 这个类实现了有关图书秒杀活动的逻辑
 *
 * createSchedule 创建某个图书的定时秒杀活动
 * 需要传入图书id   MiaoshaJobClass
 *
 *
 * */
public class MiaoShaSchedule  {
    /**
     *
     * cron表达式生成器
     * https://cron.qqe2.com/
     * name 为项目名字
     * group 为项目组
     * startTime 可为空
     * endTime 可为空
     * Clazz 业务逻辑
     * */
    public static final   SchedulerFactory schedulerFactory = new StdSchedulerFactory() ;
    public static Scheduler createSchedule(JobDetail jobDetail, CronTrigger cronTrigger) throws SchedulerException {
        Scheduler scheduler = schedulerFactory.getScheduler();
        scheduler.scheduleJob(jobDetail, cronTrigger);
        return scheduler;
    }
   /**
    *  .withIdentity("myjob") // 可以给该JobDetail起一个id，便于之后的检索
    * 。也可以 .withIdentity("myjob", "group1")
    *     .requestRecovery() // 执行中应用发生故障，需要重新执行
    *     .storeDurably() // 即使没有Trigger关联时，也不需要删除该JobDetail
    *     .usingJobData("key1", "value1")
    *     .usingJobData("key2", "value2") // 以Key-Value形式关联数据
    *   https://blog.csdn.net/catoop/article/details/70246683
    *     */
    public static JobDetail createJobDetail(Class<? extends Job> clazz,String jobName,String jobGroup,Integer bookId){
        return JobBuilder.newJob(clazz).withIdentity(jobName,jobGroup).usingJobData("bookId",bookId)
                .withDescription("秒杀图书为："+bookId)
                .storeDurably(true)
                .requestRecovery(false)
                .build();
    }

    /**
     * https://blog.csdn.net/catoop/article/details/70246683
     * forJob("myjob") // 关联上述的JobDetail
     *     .withIdentity("myjob-trigger1") // 给该Trigger起一个id
     *     .startAt(DateBuilder.futureDate(20, IntervalUnit.SECOND)) // 延迟20秒开始
     *     .withSchedule(SimpleScheduleBuilder.repeatMinutelyForever()) // 每分钟触发一次，无限循环
     *     .usingJobData("key3", "value3")
     *     .usingJobData("key4", "value4") // 以Key-Value形式关联数据
     *
     *     注意事项：
     * >  一个任务JOB可以添加多个Trigger 但是一个Trigger只能绑定一个JOB 这点需要注意。
     * >  在用JobBuilder创建JobDetail的时候，有一个storeDurably()方法，可以在没有触发器指向任务的时候，使用 sched.addJob(job, true) 将任务保存在队列中了。而后使用 sched.scheduleJob 触发。如果不使用  storeDurably ，则在添加 Job 到引擎的时候会抛异常，意思就是该 Job 没有对应的 Trigger。
     * >  要求cluster上所有的node的时间应该是一样的。
     * 过期任务处理
     *https://blog.csdn.net/GAMEloft9/article/details/89475980
     * */

    public static CronTrigger createCronTrigger(Date startTime ,Date endTime,String triggerName,String triggerGroup,String cron,JobDetail jobDetail){
        return TriggerBuilder.newTrigger().withIdentity(triggerName, triggerGroup)
                .forJob(jobDetail)
                .startNow()
            .startAt(startTime)
            .endAt(endTime)
            .withSchedule(CronScheduleBuilder.cronSchedule(cron).withMisfireHandlingInstructionDoNothing())
            .build();
    }

}
